package com.wenzi.rule.verification.actuator;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.wenzi.rule.verification.base.RuleConfig;
import org.aspectj.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.util.*;

@Service
public class DefaultActuator implements Actuator{
    private static final Log LOG = LogFactory.get(DefaultActuator.class);

    private static Map<String,Map<String,List<RuleConfig>>> configCacheMap = new HashMap<>();
    private static final String FILE_SUFFIX = ".default.json";
    private static final String CLASSPATH = "classpath:rule";

    @Override
    public String getType() {
        return "default";
    }

    @Autowired
    private void initConfigCache() throws FileNotFoundException {
        LOG.info("DefaultActuator -- Initialization rules profile caching begins");
        try {
            File classPathFile = ResourceUtils.getFile(CLASSPATH);
            if (classPathFile.isDirectory()){
                File[] configFiles = classPathFile.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        return pathname.getName().endsWith(FILE_SUFFIX);
                    }
                });

                Arrays.stream(configFiles).forEach(file->{
                    Map map = new LinkedHashMap<>();
                    try {
                        String fileString = FileUtil.readAsString(file);
                        Map ruleMap = JSONObject.parseObject(fileString, Map.class);
                        ruleMap.forEach((k,v)->{
                            map.put(k,JSON.parseArray(v.toString(),RuleConfig.class));
                        });
                        configCacheMap.put(file.getName().split(FILE_SUFFIX)[0],map);
                    }catch (Exception e){
                        //
                        LOG.error("DefaultActuator -- Profile cache setup failed");
                    }
                });
            }
        }catch (Exception e){
            LOG.error("DefaultActuator -- Failed to initialize rule profile cache");
            throw e;
        }
        LOG.info("DefaultActuator -- Initialization rules configure the end of the file cache");
    }

    @Override
    public Map<String,List<RuleConfig>> getRuleConfig(String configName) {
        LOG.info("{}:Get the rule configuration to get started",configName);
        if (StringUtils.isEmpty(configName)) return null;

        Map<String, List<RuleConfig>> innerConfigMap = configCacheMap.get(configName);
        if (Objects.isNull(innerConfigMap)){
            LOG.info("{}:No cached data, reload begins",configName);
            Map<String, List<RuleConfig>> configMap = new LinkedHashMap<>();
            try {
                File file = ResourceUtils.getFile(CLASSPATH + File.separator + configName + FILE_SUFFIX);
                String config = FileUtil.readAsString(file);
                Map<String,Object> map = JSONObject.parseObject(config, Map.class);
                map.forEach((k,v)->{
                    configMap.put(k,JSON.parseArray(v.toString(),RuleConfig.class));
                });
            } catch (Exception e) {
                LOG.error(e,"{}:Reloading the rule configuration file failed",configName);
            }
            LOG.info("{}:The reload rules file ends",configName);
            return configMap;
        }
        LOG.info("{}:Get the end of the rule configuration",configName);
        return innerConfigMap;
    }


}
